<?php

/**
 * @Author: king
 * @Date:   2019-05-04 17:03:28
 * @Last Modified by:   king
 * @Last Modified time: 2019-06-06 22:44:46
 */

namespace App\Models\Api;

use App\Exceptions\ApiException;
use App\Models\Api\Base;
use App\Models\Api\LanmeiTag;
use App\Models\Api\LanmeiCounselorProblem;
use App\Models\Api\LanmeiCounselorAnswer;
use App\Models\Api\LanmeiCounselorProblemRecode;
use AstroTool\Cache\CacheManage;
use AstroTool\Cache\ProblemAndAnswer;
use Cache;

class LanmeiCounselorProblem extends Base
{
    protected $table = 'counselor_problem';
    protected $dateFormat = 'U';
    public $guarded       = [];
    const CREATED_AT      = 'create_time';
    const UPDATED_AT      = 'update_time';
    public $timestamps    = false;
    const COUNSELOR_NUM = 'order:counselor::num'; // 问答订单数量
    /**
     * 待回答问题的排序基数 基数-当前时间戳 为排序值
     * @var int
     */
    protected $sort = 5000000000;

    /**
     * 采纳分配比例
     * @var array
     */
    protected $allotConfig = [
        2 => 0.7,
        3 => 0.56,
        4 => 0.5,
        5 => 0.45,
        6 => 0.41,
        7 => 0.38,
        8 => 0.35,
        9 => 0.32,
        10 => 0.3,
    ];

    /**
     * 咨询问题写入
     * @param $data
     * @return mixed
     * @throws \Exception
     */
    public function insertProblemData($data)
    {
        try {
            $id = $this->insertGetId($data);
        } catch (Exception $e) {
            throw new ApiException('服务异常', config('code.error'));
        }
        // 问题数据初始化
        $problemData = [
            'id' => $id,
            'uid' => $data['uid'],
            'title' => $data['title'],
            'tag_id' => $data['tag_id'],
            'problem_status' => $data['problem_status'],
            'problem_type' => $data['problem_type'],
            'bind_id' => $data['bind_id'],
            'create_time' => $data['create_time'],
            'update_time' => 0,
            'delete_time' => 0,
            'is_opened' => 0,
            'counselor_mode' => 2,
            'people' => 0,
            'answer_people' => 0,
            'counselor_ids' => '',
            'counselor_price' => '0.00',
            'read_num' => 0,
            'extend' => '',
            'status' => 1,
            'order_id' => '',
            'accept_answer' => 0,
            'suc_time' => 0,
            'pad_time' => 0,
            'answer_ids' => ''
        ];
        // 写入问题缓存
        CacheManage::getInstance()->setCacheConfig('user_problem', $problemData['id'])
            ->setCache($problemData, 'details', false);

        return $id;
    }

    /**
     * 咨询问题更新、指定写入待回答的答案
     * @param $data
     * @return bool
     * @throws \Exception
     */
    public function problemUpdate($data)
    {
        try {
            $orderData = [
                'is_opened'       => $data['is_opened'],
                'people'          => $data['people'],
                'counselor_price' => $data['counselor_price'],
                'problem_status'  => 2,
                'extend'          => '',
                'order_id'   => $data['order_id'],
                'counselor_mode'  => 2,
            ];
            $this->where(['id' => $data['id']])->update($orderData);
        } catch (Exception $e) {
            throw new ApiException('服务异常', 200, config('code.error'));
        }
        // 更新问题缓存
        CacheManage::getInstance()->setCacheConfig('user_problem', $data['id'])
            ->setCache($data, 'details', true);

        return true;
    }

    /**
     * 支付回调处理
     * @param $orderId
     * @return array
     * @throws Exception
     * @throws \db\exception\DataNotFoundException
     * @throws \db\exception\ModelNotFoundException
     * @throws \exception\DbException
     */
    public function payHandle($orderId)
    {
        $problemData = $this->where('order_id', $orderId)
            ->select('id', 'counselor_mode', 'people', 'counselor_ids', 'problem_status', 'problem_type')
            ->first();

        $time = time();
        // 问题状态更新
        $problemupdateData = [
            'update_time' => $time,
            'problem_status' => 3,
            'id' => $problemData['id']
        ];
        $result = [
            'counselorMode' => $problemData['counselor_mode'],
            'push' => []
        ];
        // 指定 创建待回答答案
        if ($problemData['counselor_mode'] == 1) {
            $answerData = [];
            $sort = $this->sort - $time; // 排序
            $counselorIds = explode(',', $problemData['counselor_ids']);
            foreach ($counselorIds as $counselorId) {
                $answerData[] = [
                    'create_time' => $time, // 创建时间
                    'cp_id' => $problemData['id'], // 问题ID
                    'c_id' => $counselorId, // 咨询师ID
                    'state' => 2, // 0正常 1被举报 2待回答
                    'sort' => $sort
                ];
            }
            // 批量写入
            $insertResult = (new LanmeiCounselorAnswer())->saveAll($answerData);

            $caIDs = [];
            foreach ($insertResult as $insterItem) {
                array_push($caIDs, $insterItem->id);
            }

            $problemupdateData['answer_ids'] = implode(',', $caIDs);

            // 增加推送消息
            $result['push'] = $counselorIds;
        } else {
            // 向问题池抛送问题
            ProblemAndAnswer::getInstance()->setCacheKey($problemData['problem_type'])->addProblem($problemData['id'], $problemData['people']);
        }
        // 问题状态更新
        $this->problemUpdate($problemupdateData);

        $queueConfig = config('queue');

        queuePush($queueConfig['problem_padding_task'], ['cp_id' => $problemData['id']], $queueConfig['problem_padding_queue'], $queueConfig['problem_padding_delay']);

        $this->orderNumInc($problemData['problem_type'], $problemData['problem_type'] == 1 ? 8 : 7);

        return $result;
    }

    /**
     * 订单数增加
     * @param $problemType
     * @param $orderType
     */
    public function orderNumInc($problemType, $orderType)
    {
        try {
            // 订单统计数增加
            $item = $problemType == 1 ? 'stargazer' : 'divination'; // stargazer占星 divination占卜

            \DB::table('astro_order_total')->where('order_type', $orderType)->increment('total', 1);

            // 更新 订单数 缓存
            CacheManage::getInstance()->setCacheConfig('orders_counselor_num')->hashDataInc($item, 1, function () use ($orderType) {
                return \DB::table('astro_order_total')->where('order_type', $orderType)->value('total') ?? 0;
            });
        } catch (\Exception $e) {
        }
    }

    /**
     * 获取占星(占卜)咨询订单次数
     * @return array
     * @throws \Exception
     */
    public function getOrderTotalNum()
    {
        $data = (CacheManage::getInstance()->setCacheConfig('orders_counselor_num')->getCache('', 'details')) ?? [];

        $d = [];
        if (!isset($data['stargazer'])) {
            $d[] = 8;
        }

        if (!isset($data['divination'])) {
            $d[] = 7;
        }

        if ($d) {
            try {
                $arr = \DB::table('astro_order_total')->whereIn('order_type', $d)->pluck('total', 'order_type');
            } catch (Exception $e) {
                $arr = [];
            }

            $data['divination'] = $arr[8] ?? ($data['divination'] ?? 0);
            $data['stargazer'] = $arr[7] ?? ($data['stargazer'] ?? 0);
            CacheManage::getInstance()->setCacheConfig('orders_counselor_num')->setCache($data, 'details', true);
        }

        $total = [
            'sta' => $data['stargazer'],
            'div' => $data['divination']
        ];

        return $total;
    }

    /**
     * 在数据库中通过IDS批量获取问题详情
     * @param $cpIds
     * @return array
     * @throws ApiException
     */
    protected function batchGetInfoByIdsInData($cpIds)
    {
        try {
            $data = $this->whereIn('id', $cpIds)->get(['id', 'create_time', 'update_time', 'delete_time', 'tag_id', 'title', 'is_opened', 'problem_type', 'counselor_mode', 'people', 'counselor_ids', 'answer_people', 'counselor_price', 'problem_status', 'read_num', 'extend', 'status', 'order_id', 'suc_time', 'pad_time', 'bind_id', 'uid', 'accept_answer', 'answer_ids'])->keyBy('id')->toArray();
        } catch (Exception $e) {
            throw new ApiException('服务异常', 200, config('code.error'));
        }

        return $data;
    }

    /**
     * 通过问题ID 批量查询问题信息并指定字段
     * @param $cpIds
     * @param array|string $field
     * @return array
     * @throws \Exception
     */
    public function batchGetProblemInfoByIds($cpIds, $field = [])
    {
        $cpIds = is_array($cpIds) ? $cpIds : explode(',', $cpIds);

        $data = CacheManage::getInstance()->setCacheConfig('user_problem')
            ->batchGetCache($cpIds, function ($ids) {
                return $this->batchGetInfoByIdsInData($ids);
            }, $field, 'list_details');

        return $data;
    }

    /**
     * 获取问答广场数据
     * @return array
     * @throws ApiException
     * @throws \Exception
     */
    public function getProblemIndex()
    {
        try {
            $data = $this->where('delete_time', 0)->where('status', 1)->whereIn('problem_status', [3, 4, 5])
                ->orderBy('update_time', 'desc')
                ->select('id', 'title', 'update_time', 'is_opened', 'tag_id', 'problem_type', 'counselor_mode', 'people', 'counselor_price', 'problem_status', 'bind_id', 'answer_people', 'read_num', 'problem_status')
                ->limit(10)
                ->get();
        } catch (Exception $e) {
            throw new ApiException('服务异常', 200, config('code.error'));
        }

        $problemData = $this->problemDataReset($data);

        return $problemData;
    }

    /**
     * 问答广场更多分页数据
     * @param $whereParam
     * @return array
     * @throws ApiException
     * @throws \Exception
     */
    public function getProblemList($whereParam)
    {
        $where = [];
        if ($whereParam['type']) {
            $where['problem_type'] = $whereParam['type'];
        }

        if ($whereParam['cid']) {
            $where['tag_id'] = $whereParam['cid'];
        }

        if ($whereParam['status']) {
            if ($whereParam['status'] == 1) { // 完成
                $where['problem_status'] = 5;
            } else { // 未完成
                $where['problem_status'] = ['in', [3, 4]];
            }
        } else {
            $where['problem_status'] = ['in', [3, 4, 5]];
        }

        try {
            // 查询数据
            $data = $this->where('delete_time', 0)->where('status', 1)->whereIn('problem_status', [3, 4, 5])->raw($where)
                ->orderBy('update_time', 'desc')
                ->select('id', 'title', 'update_time', 'is_opened', 'tag_id', 'problem_type', 'counselor_mode', 'people', 'counselor_price', 'problem_status', 'bind_id', 'answer_people', 'read_num', 'problem_status')
                ->paginate(10)->toArray();

            $data['data'] = $this->problemDataReset($data['data']);
        } catch (Exception $e) {
            throw new ApiException('服务异常', 200, config('code.error'));
        }

        return $data;
    }

    /**
     * 列表的数据重组
     * @param $data
     * @return array
     * @throws \Exception
     */
    public function problemDataReset($data)
    {
        // 获取占星档案ID和占卜ID
        $stargazerIds = '';
        $divinationIds = [];
        foreach ($data as $dataItem) {
            if ($dataItem['problem_type'] == 1) { //占星
                $stargazerIds = $stargazerIds . ',' . $dataItem['bind_id'];
            } else { //占卜
                array_push($divinationIds, $dataItem['bind_id']);
            }
        }
        $stargazerIds = ltrim($stargazerIds, ',');

        $stargazerData = [];
        if (!empty($stargazerIds)) {   // 占星数据
            $stargazerData = (new LanmeiCounselorProblemRecode())->getProblemRecodeName($stargazerIds);
        }

        $divinationData = [];
        if (!empty($divinationIds)) {   // 占卜数据
            $divinationData = (new Divination())->getDetailsByIds($divinationIds);
        }

        $problemData = [];

        $tagData = LanmeiTag::getTagData(1);

        foreach ($data as $problemItem) {
            $timeName = in_array($problemItem['problem_status'], [1, 2]) ? 'create_time' : 'update_time';

            $r = [
                'cp_id' => $problemItem['id'],
                'title' => $problemItem['title'],
                'type' => $problemItem['problem_type'],
                'is_opened' => $problemItem['is_opened'],
                'people' => $problemItem['people'],
                'answer_people' => $problemItem['answer_people'],
                'read_num' => $problemItem['read_num'],
                'time' => date('Y-m-d H:i', $problemItem[$timeName]),
                'price' => $problemItem['counselor_price'],
                'tag_name' => $tagData[$problemItem['tag_id']],
                'status' => $problemItem['problem_status']
            ];

            if ($problemItem['problem_type'] == 1) {
                foreach (explode(',', $problemItem['bind_id']) as $rid) {
                    $r['stargazer_info'][] = $stargazerData[$rid];
                }
            } else {
                $r['divination_info'] = [
                    'planet' => $divinationData[$problemItem['bind_id']]['planet'],
                    'sign' => $divinationData[$problemItem['bind_id']]['sign'],
                    'house' => $divinationData[$problemItem['bind_id']]['house'],
                    'did' => $divinationData[$problemItem['bind_id']]['id'],
                ];
            }

            array_push($problemData, $r);
        }

        return $problemData;
    }

    /**
     * 批量获取问题占星档案或者单个占卜结果 信息
     * @param string $bindId 类型的关联ID
     * @param $problemType 问题类型 1占星 2占卜
     * @return array
     * @throws \Exception
     */
    public function getBindData($bindId, $problemType)
    {
        $data = [];
        if ($problemType == 1) {
            //占星
            $data['stargazer_info'] = array_values((new LanmeiCounselorProblemRecode())->getProblemRecodeName($bindId));
        } else {
            //占卜
            $divination = (new Divination())->getDetail(['id' => $bindId]);
            $data['divination_info'] = [
                'planet' => $divination['planet'],
                'sign' => $divination['sign'],
                'house' => $divination['house'],
                'did' => $divination['id'],
            ];
        }

        return $data;
    }

    /**
     * 通过问题ID获取问题信息 单条
     * @param $cpId
     * @param array $field
     * @return array|mixed
     * @throws \Exception
     */
    public function getProblemInfoById($cpId, $field = [])
    {
        $data = $this->batchGetProblemInfoByIds($cpId, $field);

        $data = current($data);

        return $data;
    }

    /**
     * 获取我的问题所有
     * @param int $uid
     * @param int $page
     * @return array
     * @throws \Exception
     */
    public function getMyProblemList($uid = 0, $page = 1)
    {
        // 查询数据
        $where = ['delete_time' => 0, 'uid' => $uid];
        try {
            $data = $this->where($where)
                ->select('id', 'title', 'create_time', 'update_time', 'is_opened', 'tag_id', 'problem_type', 'counselor_mode', 'people', 'counselor_price', 'problem_status', 'bind_id', 'answer_people', 'read_num', 'problem_status')
                ->orderBy('update_time', 'desc')
                ->paginate(10, $page)->toArray();
        } catch (\Exception $e) {
            throw new ApiException('获取我的问题列表失败', 200, config('code.error'));
        }
        $data['data'] = $this->problemDataReset($data['data']);

        return $data;
    }

    /**
     * 获取用户提问的 问题ID --> 缓存
     * @param $uid
     * @return array
     * @throws \Exception
     */
    public function getUserProblemIds($uid)
    {
        $result = CacheManage::getInstance()->setCacheConfig('user_problem', $uid)
            ->ZsGetIocData('list', function () use ($uid) {
                return $this->getUserProblemIdsData($uid);
            });

        return $result;
    }

    /**
     * 获取用户提问的所有问题ID
     * @param $uid
     * @return array [$id=>$id]
     * @throws ApiException
     */
    protected function getUserProblemIdsData($uid)
    {
        try {
            $ids = $this->where('delete_time', 0)->where('uid', $uid)->pluck('id'); // 获取用户提问的 问题ID

            $data = [];
            foreach ($ids as $id) {
                $data[] = [$id => $id];
            }
        } catch (Exception $e) {
            throw new ApiException('服务异常', 200, config('code.error'));
        }

        return $data;
    }

    /**
     * 向缓存中添加用户提问的 问题ID
     * @param $uid
     * @param $cpId
     * @throws \Exception
     */
    public function addUserProblemID($uid, $cpId)
    {
        CacheManage::getInstance()->setCacheConfig('user_problem', $uid)
            ->setCacheTime(0)
            ->ZsAddIocData([$cpId => $cpId], 'list', function () use ($uid) {
                return $this->getUserProblemIdsData($uid);
            });
    }

    /**
     * 咨询师 问答回复
     * @param $cid
     * @param bool $isSelf 是不是本人
     * @return array
     * @throws \Exception
     * @throws \db\exception\DataNotFoundException
     * @throws \db\exception\ModelNotFoundException
     * @throws \exception\DbException
     */
    public function getCounsoleAnswerToProblemList($cid, $isSelf = false)
    {
        $answerList = (new LanmeiCounselorAnswer())->getCounselorAnswerList($cid, $isSelf);

        if (empty($answerList['data'])) {
            return $answerList;
        }
        $cpId = [];
        foreach ($answerList['data'] as $answerItem) {
            array_push($cpId, $answerItem['cp_id']);
        }

        $problemListInfo = $this->batchGetProblemInfoByIds($cpId, 'id,title,problem_type,is_opened,people,answer_people,read_num,update_time,counselor_price,tag_id,problem_status,bind_id');
        // 获取问题列表数据
        $resetData = $this->problemDataReset($problemListInfo);
        // 格式重组
        $rdata = [];
        foreach ($resetData as $resetDatum) {
            $rdata[$resetDatum['cp_id']] = $resetDatum;
        }
        $answerProblemData = [];
        foreach ($answerList['data'] as $answerItem) {
            // 判断问题状态 1已举报 2待回答 3过期未回答 4待结算 5完成
            $status = $answerItem['state'] > 0 ? $answerItem['state'] : (in_array($rdata[$answerItem['cp_id']]['status'], [3, 4]) ? 4 : 5);

            $rdata[$answerItem['cp_id']]['read_num'] = $answerItem['read_num'];
            $rdata[$answerItem['cp_id']]['status'] = $status;
            $rdata[$answerItem['cp_id']]['time'] = date('Y-m-d H:i', strtotime($answerItem['create_time']));
            $rdata[$answerItem['cp_id']]['is_comment'] = $answerItem['is_comment'];
            $rdata[$answerItem['cp_id']]['is_accept'] = $answerItem['is_accept'];
            $rdata[$answerItem['cp_id']]['ca_id'] = $answerItem['id'];
            $end_time = 0;
            if ($status == 2) {
                $end_time =  strtotime($answerItem['create_time']) + 86400 - time();
                $end_time = $end_time > 0 ? $end_time : 0;
            }
            $rdata[$answerItem['cp_id']]['end_time'] = $end_time;
            $rdata[$answerItem['cp_id']]['is_opened'] = (int)$rdata[$answerItem['cp_id']]['is_opened'];

            $answerProblemData[] = $rdata[$answerItem['cp_id']];
        }

        $answerList['data'] = $answerProblemData;
        $answerList['is_self'] = $isSelf ? 1 : 0;

        return $answerList;
    }

    /**
     * 问题进入结算中 【结算之前自行判断状态 是否还在待回答状态|当前回答人数已满】
     * @param $cpId 问题ID
     * @param $problemMode 咨询方式 2公开悬赏  1指定悬赏
     * @param $problemType 问题类型 1占星  2占卜
     * @return bool
     * @throws \Exception
     */
    public function problemEnterSettlement($cpId, $problemMode, $problemType)
    {
        // 问题状态更新进入待结算
        $this->problemUpdate(['id' => $cpId, 'pad_time' => time(), 'problem_status' => 4]);
        // 如果是公开悬赏 删除悬赏池里面的悬赏问题ID
        if ($problemMode == 2) {   // 删除问题
            ProblemAndAnswer::getInstance()->setCacheKey($problemType)->delProblem($cpId);
        } else {   // 指定 未回答的问题关闭 状态更新
            (new LanmeiCounselorAnswer())->save(['state' => 3, 'sort' => time()], ['cp_id' => $cpId]);
        }

        return true;
    }

    /**
     * 问题结算完成
     * @param $data
     * @return bool
     * @throws \Exception
     */
    public function problemSuccess($data)
    {
        $problemAnswerModel = new LanmeiCounselorAnswer();
        $time = time();
        $problemSuccess = [
            'suc_time' => $time,
            'problem_status' => 5,
            'extend' => json_decode($data['extend'], true)
        ];
        // 获取答案信息
        $answerList = $problemAnswerModel->getAnswerListByCpid($data['id'], 'ca.c_id,ca.state,ca.is_accept,ca.is_comment,cac.grade');

        $caIds = array_keys($answerList); // 答案ID
        $problemSuccess['answer_people'] = count($caIds); // 更新回答人数
        $counselorGrade = []; // 咨询师赚取积分 答题 积分信息
        $counselorPrice = []; // 咨询师赚取金钱
        $defaultComment = []; // 默认评价
        $informComment = []; // 举报评价 评分1星 更新
        $updateCounselorInfo = []; // 咨询师信息变更 用于重新统计咨询师 星级 采纳率等
        $backPrice = 0; // 退款金额

        if ($data['counselor_mode'] == 1) { // 如果是指定悬赏
            $extend = $problemSuccess['extend']['counselor_info'];
            foreach ($extend as $cInfo) {
                $counselorPrice[$cInfo['id']] = $cInfo['price'] * 0.7;
            }

            foreach ($answerList as $answerId => $answerItem) {
                $updateCounselorInfo[$answerItem['c_id']] = [ // 默认值
                    'is_accept' => 0,
                    'is_inform' => 0,
                ];
                switch ($answerItem['state']) {
                    case 0:
                        // 获取积分
                        if ($answerItem['grade']) {
                            $counselorGrade[$answerItem['c_id']] = [
                                'integral' => $answerItem['grade'] * 0.1,
                                'ca_id' => $answerId,
                                'create_time' => $time
                            ];
                        } else {
                            $counselorGrade[$answerItem['c_id']] = [
                                'integral' => 0.5,
                                'ca_id' => $answerId,
                                'create_time' => $time
                            ]; // 默认积分
                            // 添加默认评价
                            $defaultComment[] = [
                                'create_time' => $time,
                                'grade' => 5,
                                'ca_id' => $answerId,
                                'uid' => 0,
                                'c_id' => $answerItem['c_id']
                            ];
                        }
                        if ($answerItem['is_accept'] == 1) {
                            $counselorGrade[$answerItem['c_id']]['integral'] += 0.5;
                            $updateCounselorInfo[$answerItem['c_id']]['is_accept'] = 1;
                        }
                        $problemSuccess['extend']['answer_price'][$answerId] = $counselorPrice[$answerItem['c_id']];
                        break;
                    case 1:
                        $counselorGrade[$answerItem['c_id']] = [
                            'integral' => -5,
                            'ca_id' => $answerId,
                            'create_time' => $time
                        ];
                        // 已经举报并审核通过 增加退款
                        $backPrice += ($counselorPrice[$answerItem['c_id']] / 0.7);
                        // 不是正常情况（举报中|未回答|已举报） 不给咨询师 赏金
                        unset($counselorPrice[$answerItem['c_id']]);
                        // 添加默认评价
                        if ($answerItem['grade']) {
                            $defaultComment[] = [
                                'create_time' => $time,
                                'grade' => 1,
                                'ca_id' => $answerId,
                                'uid' => 0,
                                'c_id' => $answerItem['c_id']
                            ];
                        } else {
                            array_push($informComment, $answerId);
                        }
                        $problemSuccess['extend']['answer_price'][$answerId] = 0;
                        $updateCounselorInfo[$answerItem['c_id']]['is_inform'] = 1;
                        break;
                    default:
                        $problemSuccess['extend']['no_suc'][] = [
                            'ca_id' => $answerId,
                            'price' => $counselorPrice[$answerItem['c_id']]
                        ];
                        // 不是正常情况（举报中|未回答|已举报） 不给咨询师 赏金
                        unset($counselorPrice[$answerItem['c_id']]);

                        if ($answerItem['state'] == 4) {
                            $problemSuccess['extend']['answer_price'][$answerId] = $counselorPrice[$answerItem['c_id']];
                        } else {
                            $problemSuccess['extend']['answer_price'][$answerId] = 0;
                        }
                }

                $problemSuccess['extend']['answer_price'][] = [
                    'ca_id' => $answerId,
                    'price' => $counselorPrice[$answerItem['c_id']]
                ];
            }
        } else { // 公开悬赏
            if ($data['accept_answer']) {   // 有问题被采纳
                $acceptPrice = $this->allotConfig[$data['people']] * $data['counselor_price']; // 咨询师 采纳价
                $counPrice = ($data['counselor_price'] - $acceptPrice) / ($data['people'] - 1); // 咨询师 非采纳价
            } else {   // 没有问题被采纳
                $counPrice = $data['counselor_price'] / ($data['people']); // 咨询价
            }

            // 退款金额
            $backPrice = ($data['people'] - $data['answer_people']) * $counPrice;

            foreach ($answerList as $answerId => $answerItem) {
                $updateCounselorInfo[$answerItem['c_id']] = [ // 默认值
                    'is_accept' => 0,
                    'is_inform' => 0,
                ];
                switch ($answerItem['state']) {
                    case 0:
                        // 获取积分
                        if ($answerItem['grade']) {
                            $counselorGrade[$answerItem['c_id']] = [
                                'integral' => $answerItem['grade'] * 0.1,
                                'ca_id' => $answerId,
                                'create_time' => $time
                            ]; // 评价积分
                        } else {
                            $counselorGrade[$answerItem['c_id']] = [
                                'integral' => 0.5,
                                'ca_id' => $answerId,
                                'create_time' => $time
                            ]; // 默认积分
                            // 添加默认评价
                            $defaultComment[] = [
                                'create_time' => $time,
                                'grade' => 5,
                                'ca_id' => $answerId,
                                'uid' => 0,
                                'c_id' => $answerItem['c_id']
                            ];
                        }

                        if ($answerItem['is_accept'] == 1) {
                            $price = $acceptPrice * 0.7; // 平台收取30% 服务费
                            $counselorPrice[$answerItem['c_id']] = $price;
                            $problemSuccess['extend']['answer_price'][$answerId] = $price;
                            $counselorGrade[$answerItem['c_id']]['integral'] += 0.5; // 采纳了增加额外积分
                            $updateCounselorInfo[$answerItem['c_id']]['is_accept'] = 1;
                        } else {
                            $price = $counPrice * 0.7; // 平台收取30% 服务费
                            $counselorPrice[$answerItem['c_id']] = $price; // 平台收取30% 服务费
                            $problemSuccess['extend']['answer_price'][$answerId] = $price;
                        }
                        break;
                    case 1:
                        $counselorGrade[$answerItem['c_id']] = [
                            'integral' => -5,
                            'ca_id' => $answerId,
                            'create_time' => $time
                        ]; // 咨询师被举报 扣除积分
                        // 添加默认评价
                        if ($answerItem['grade']) {
                            $defaultComment[] = [
                                'create_time' => $time,
                                'grade' => 1,
                                'ca_id' => $answerId,
                                'uid' => 0,
                                'c_id' => $answerItem['c_id']
                            ];
                        } else {
                            array_push($informComment, $answerId);
                        }
                        $backPrice += $counPrice;   // 退款金额
                        $problemSuccess['extend']['answer_price'][$answerId] = 0;
                        $updateCounselorInfo[$answerItem['c_id']]['is_inform'] = 1;
                        break;
                    default:
                        // 其他情况暂时不做积分变更
                        $problemSuccess['extend']['no_suc'][] = [
                            'ca_id' => $answerId,
                            'price' => $counselorPrice[$answerItem['c_id']]
                        ];
                        if ($answerItem['state'] == 4) {
                            $problemSuccess['extend']['answer_price'][$answerId] = $counPrice;
                        } else {
                            $problemSuccess['extend']['answer_price'][$answerId] = 0;
                        }
                }

                $problemSuccess['extend']['answer_price'][$answerId] = $counselorPrice[$answerItem['c_id']];
            }
        }

        \DB::beginTransaction();
        try {
            // 未评价答案 -->生成默认评价,已举报评价默认1星
            (new LanmeiCounselorAnswerComment())->createDefault($defaultComment, $informComment);
            // 咨询师 积分 变更 -->并判断是否有升级情况
            $counRes = (new LanmeiCounselor())->sucIntegrUpdate($counselorGrade, $data['counselor_mode']);
            // 咨询师 账户 入账
            (new LanmeiUserAccount())->counselorAccountAdd($counselorPrice, $data['id'], $time);

            $counselorAnswerModel = new LanmeiCounselorAnswer();
            foreach ($problemSuccess['extend']['answer_price'] as $answerId => $answerPrice) {
                $counselorAnswerModel->save(['price' => $answerPrice, 'is_comment' => 1], ['id' => $answerId]);
                CacheManage::getInstance()->setCacheConfig('counselor_problem_answer', $answerId)->rmCache('details');
            }

            if ($backPrice) { // 创建退款订单
                $refund_id = (new LanmeiOrderRefund())->creatOrder($data['order_id'], 1, $backPrice);
            }

            // 更新问题详情
            $problemSuccess['extend'] = json_encode($problemSuccess['extend']);
            $this->where('id', $data['id'])->update($problemSuccess);

            \DB::commit();
        } catch (Exception $e) {
            \DB::rollback();
            \Log::info('问题ID【' . $data['id'] . '】结算失败：' . $e->getMessage() . date('Y-m-d H:i:s') . PHP_EOL);
            return false;
        }

        $queueConfig = config('queue');
        // 发送更新咨询师 星级 采纳率 队列
        queuePush($queueConfig['update_counselor_task'], $updateCounselorInfo, $queueConfig['update_counselor_queue'], $queueConfig['update_counselor_delay']);
        if ($backPrice && !empty($refund_id)) {   // 有退款 --> 退款队列
            queuePush($queueConfig['problem_refund_task'], ['refund_id' => $refund_id], $queueConfig['problem_refund_queue'], $queueConfig['problem_refund_delay']);
        }

        $cacheModel = CacheManage::getInstance();
        // 缓存处理
        // 更新问题详情
        $cacheModel->setCacheConfig('user_problem', $data['id'])->setCache($problemSuccess, 'details', true);
        foreach ($counselorGrade as $cid => $item) {   // 删除咨询师的信息
            $cacheModel->setCacheConfig('counselor_info', $cid)->rmCache('details');
        }

        if (isset($counRes['up_level']) && !empty($counRes['up_level'])) {   // 添加升级提示
            foreach ($counRes['up_level'] as $cid => $upInfo) {   // 添加升级提示
                $userCounselorData = (new LanmeiUserCounselorStatus)->getUserCounselorStatus($upInfo['uid']);
                $updateData = isset($userCounselorData['update_data']) ? json_decode($userCounselorData['update_data'], true) : [];
                // 组合升级信息
                $updateData[] = [
                    'level' => $upInfo['level'],
                    'type' => $upInfo['type'],
                    'level_name' => $upInfo['level_name'],
                ];
                // 设置升级信息缓存
                $cacheModel->setCacheConfig('user_counselor_status', $upInfo['uid'])->setCache(['update_data' => json_encode($updateData)], 'details', true);
            }
        }

        return true;

        /**
         * 开启事物-->
         *
         * 问题状态完成
         * 是否有退款-->有 发送退款队列
         *      退款流水
         *      退款申请
         * 是否有举报
         *      审核中-->冻结
         *      已审核-->咨询师积分扣除 && 退款
         *
         * 占星师金额计算-》分配
         * 占星师积分增加 --> 判断咨询师升级了没有
         * 自动评论
         * 账户流水
         * 更新答案表数据 price
         */
    }

    /**
     * 问题关闭
     * @param $cpId 问题ID
     * @param $problemMode 咨询方式 2公开悬赏  1指定悬赏
     * @param $problemType 问题类型 1占星  2占卜
     * @param $order_id
     * @return bool
     * @throws ApiException
     * @throws \Exception
     * @throws \XznsTools\exception\ApiException
     */
    public function problemClosed($cpId, $problemMode, $problemType, $order_id)
    {
        // 问题状态更新 问题关闭
        $this->problemUpdate(['id' => $cpId, 'pad_time' => time(), 'problem_status' => 6]);
        // 如果是公开悬赏 删除悬赏池里面的悬赏问题ID
        if ($problemMode == 2) {   // 删除问题
            ProblemAndAnswer::getInstance()->setCacheKey($problemType)->delProblem($cpId);
        } else {   // 指定 未回答的问题关闭 状态更新
            (new LanmeiCounselorAnswer())->save(['state' => 3, 'sort' => time()], ['cp_id' => $cpId]);
        }

        // 创建退款订单
        $refund_id = (new LanmeiOrderRefund())->creatOrder($order_id, 3);
        //  退款推送
        $queueConfig = config('queue');
        queuePush($queueConfig['problem_refund_task'], ['refund_id' => $refund_id], $queueConfig['problem_refund_queue'], $queueConfig['problem_refund_delay']);

        return true;
    }
}
